import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.Serializable;
import java.net.UnknownHostException;

import javax.swing.BoxLayout;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;


public class MainWindow implements Serializable{

	private JFrame frame;
	private PanelSpelbord spelbordPanel;
	private MainWindow mainWindow = this;
	private SpelManager spelManager;
	private Color ownColor;
	private boolean spelGestart;
	private boolean pauze;
	private int interval;

	
	/**
	 * Create the application
	 */
	public MainWindow() {
		try {
			spelManager = new SpelManager(this);
			spelGestart = false;
		} catch (UnknownHostException e) {
			System.out.println("Fout bij aanmaken multicaster!");
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		initialize();
		frame.setVisible(true);
		pauze = false;
	}

	/**
	 * Create the application
	 */
	public MainWindow(Spelbord spelbord) {
		//this.spelbord = spelbord;
		initialize();
		frame.setVisible(true);
		this.ownColor = null;
	}

	/**
	 * Initialize the contents of the frame
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setName("Vier op een rij");
		frame.setTitle("Vier op een rij");
		frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
		frame.setSize(800, 600);
		frame.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent we){
				sluitSpelAf();
			}
			}); 
		

		final JMenuBar menuBar = new JMenuBar();
		frame.setJMenuBar(menuBar);

		final JMenu fileMenu = new JMenu();
		fileMenu.setText("Bestand");
		menuBar.add(fileMenu);

		final JMenuItem newGameMenuItem = new JMenuItem();
		newGameMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent arg0) {
				startSpel();
			}
		});
		newGameMenuItem.setText("Nieuw spel");
		fileMenu.add(newGameMenuItem);

		final JMenuItem freezeMenuItem = new JMenuItem();
		freezeMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent arg0) {
				spelManager.zendPauze();
			}
		});
		freezeMenuItem.setText("Freeze");
		fileMenu.add(freezeMenuItem);

		final JMenuItem exitMenuItem = new JMenuItem();
		exitMenuItem.addMouseListener(new MouseAdapter() {
			public void mousePressed(final MouseEvent arg0) {
				sluitSpelAf();
			}
		});
		exitMenuItem.setText("Afsluiten");
		fileMenu.add(exitMenuItem);
	}
	
	public int getInterval() {
		return interval;
	}
	
	public void setInterval(int interval) {
		this.interval = interval;
	}
	
	public void sluitSpelAf() {
		if (spelGestart)
			spelManager.leaveSpel();
		System.exit(0);
	}
	
	
	public void startSpel() {
		chooseColor();
		if (ownColor != null) {
			FrameJoiningGame joinGameFrame = new FrameJoiningGame();
			joinGameFrame.setVisible(true);
			int returnWaardeJoin = spelManager.joinBezigSpel(ownColor);
			joinGameFrame.dispose();
			// nog geen spel bezig -> start zelf een spel op
			if (returnWaardeJoin == SpelManager.GEEN_SPEL_BEZIG)
			{
				FrameNewGame newGame = new FrameNewGame(mainWindow);
				newGame.setVisible(true);
			}
			// we joinen een spel dat bezig is
			else if (returnWaardeJoin == SpelManager.JOIN_ACCEPTED)
				spelGestart = true;
			// we moeten onze kleur herkiezen
			else if (returnWaardeJoin == SpelManager.HERKIES_KLEUR) {
				joinGameFrame.dispose();
				JOptionPane.showMessageDialog(frame, "De kleur is al bezet, kies een nieuwe kleur.", "Herkies kleur", JOptionPane.ERROR_MESSAGE);
				startSpel();
			}
		}
	}
	
	public SpelManager getSpelManager() {
		return spelManager;
	}

	public void addSpelbordPanel(int rows, int cols) {
		if (spelbordPanel != null)
			frame.remove(spelbordPanel);
		spelbordPanel = new PanelSpelbord(this, rows, cols);
		frame.getContentPane().add(spelbordPanel);
		frame.validate();	
		spelGestart = true;
	}
	
	public void chooseColor() {
		ownColor = JColorChooser.showDialog(frame,
                "Choose color",
                 Color.red);
	}

	public void doMove(int x, int y, Color color) {
		spelbordPanel.setColorField(x, y, color);
	}
	
	public void doMove(int x) {
		try {
			spelManager.doeZet(x);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * wordt opgeroepen bij joinen van een spel wanneer de gebruiker een kleur gekozen heeft
	 * deze kleur moet ingesteld worden als eigen kleur en geverifieerd worden of deze nog wel
	 * beschikbaar is door een message te zenden
	 * 
	 * @param color kleur die ingevuld moet worden als eigen kleur
	 */
	public void setOwnColor(Color color) {
		this.ownColor = color;
	
	}

	public void startNewSpel(int rows, int cols, int interval, int winstconditie) {
		// TODO: nog aanvullen
		if (spelManager.startNewSpel(rows, cols, winstconditie, ownColor)) {
			mainWindow.addSpelbordPanel(rows, cols);
			spelGestart = true;
			this.interval = interval;
		}
		else
			if (JOptionPane.showConfirmDialog(frame, "Er is reeds een ander spel gestart wilt u dit joinen. Druk op No om het programma af te sluiten.", "Error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE) == JOptionPane.YES_OPTION) 
				startSpel();
			else
				System.exit(0);
				
		
		
	}
	
	public void spelAfgelopen(String message) {
		JOptionPane.showMessageDialog(frame, message, "Spel afgelopen", JOptionPane.INFORMATION_MESSAGE);
		sluitSpelAf();
	}

	public PanelSpelbord getSpelbordPanel() {
		return spelbordPanel;
	}

	public void setSpelbordPanel(PanelSpelbord spelbordPanel) {
		if (this.spelbordPanel != null)
			frame.remove(spelbordPanel);
		this.spelbordPanel = spelbordPanel;
		frame.getContentPane().add(this.spelbordPanel);
	}

	public JFrame getFrame() {
		return frame;
	}

	public void setFrame(JFrame frame) {
		this.frame = frame;
	}

	public void setPauze(boolean pauze) {
		if (pauze)
			spelbordPanel.disableButtons();
		else
			spelbordPanel.enableButtons();
	}

	public void waitInterval() {
		spelbordPanel.disableButtons();
		frame.validate();
		try {
			Thread.sleep(interval*1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		spelbordPanel.enableButtons();
		frame.validate();
	}
}
